/**
 * WebSocket 聊天服务
 * 连接到 Go 后端 WebSocket 服务器
 */
import config from './config.js'
import notificationService from './notification-service.js'

// 全局在线用户计数器
let globalActiveUsersCount = 0
const activeUsersCallbacks = []

// 获取当前活跃用户数量
export const getActiveUsersCount = () => globalActiveUsersCount

// 监听活跃用户数量变化
export const onActiveUsersChange = (callback) => {
  if (!activeUsersCallbacks.includes(callback)) {
    activeUsersCallbacks.push(callback)
  }
}

// 移除活跃用户变化监听
export const removeActiveUsersChangeCallback = (callback) => {
  const index = activeUsersCallbacks.indexOf(callback)
  if (index > -1) {
    activeUsersCallbacks.splice(index, 1)
  }
}

// 更新活跃用户数量
const updateActiveUsersCount = (change) => {
  globalActiveUsersCount = Math.max(0, globalActiveUsersCount + change)
  activeUsersCallbacks.forEach(callback => {
    try {
      callback(globalActiveUsersCount)
    } catch (error) {
      console.error('活跃用户回调执行失败:', error)
    }
  })
  console.log('当前活跃用户数量:', globalActiveUsersCount)
}

class WebSocketChatService {
  constructor() {
    this.ws = null
    this.isConnected = false
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 3 // 减少最大重连次数
    this.reconnectInterval = 3000
    this.messageCallbacks = []
    this.statusCallbacks = []
    this.heartbeatTimer = null
    this.heartbeatInterval = 30000 // 30秒心跳
    this.reconnectTimeoutId = null // 重连定时器ID
    this.hasReachedMaxAttempts = false // 是否已达到最大重连次数
    // 动态获取WebSocket服务器地址
    const serverURL = config.getServerURL().replace('http://', 'ws://')
    this.serverUrl = `${serverURL}/chat/ws`
    
    // 聊天模式相关
    this.joinedRooms = new Set() // 已加入的房间集合
    this.globalRoomId = 'global' // 全局广播房间ID
    this.defaultPrivateRoomPrefix = 'pm_' // 私聊房间前缀

    // 当前在线用户集合（由服务器广播维护）
    this.onlineUserSet = new Set()
    
    // 在线状态变化回调
    this.onlineStatusCallbacks = []
    
    // 最后一次在线用户列表更新时间
    this.lastOnlineUsersUpdate = 0
    
    // 通知相关
    this.notificationEnabled = true // 是否启用通知
  }

  // 兼容旧代码: isInitialized 与 isConnected 含义相同
  get isInitialized() {
    return this.isConnected
  }
  // 判断某用户是否在线
  isUserOnline(userId) {
    if (!this.isConnected) return false // 如果WS未连接，直接返回离线
    return this.onlineUserSet.has(Number(userId))
  }
  
  // 监听在线状态变化
  onOnlineStatusChange(callback) {
    if (!this.onlineStatusCallbacks.includes(callback)) {
      this.onlineStatusCallbacks.push(callback)
    }
  }
  
  // 移除在线状态变化监听
  removeOnlineStatusCallback(callback) {
    const index = this.onlineStatusCallbacks.indexOf(callback)
    if (index > -1) {
      this.onlineStatusCallbacks.splice(index, 1)
    }
  }
  // 手动重试连接
  async manualRetry() {
    console.log('手动重试WebSocket连接')
    this.hasReachedMaxAttempts = false
    this.reconnectAttempts = 0
    this.manualDisconnect = false
    
    // 清除重连定时器
    if (this.reconnectTimeoutId) {
      clearTimeout(this.reconnectTimeoutId)
      this.reconnectTimeoutId = null
    }
    
    // 尝试重新连接
    await this.init()
  }

  // 初始化 WebSocket 连接
  async init() {
    try {
      // 重置手动断开标记
      this.manualDisconnect = false
      if (!this.hasReachedMaxAttempts) {
        // 只有在未达到最大重连次数时才重置重连计数
        // this.reconnectAttempts = 0  // 不重置，保持重连计数
      }
      
      // 如果已经连接，直接返回
      if (this.isConnected && this.ws && this.ws.readyState === WebSocket.OPEN) {
        console.log('WebSocket 已经连接，跳过初始化')
        // 即使已连接，也主动请求一次在线用户列表
        this.requestOnlineUsers()
        return
      }
      
      // 如果存在旧连接，先关闭
      if (this.ws) {
        console.log('关闭旧连接')
        this.ws.close()
        this.ws = null
        this.isConnected = false
      }
      
      console.log('开始初始化WebSocket连接...')
      
      // 获取用户信息
      const currentUser = this.getCurrentUser()
      if (!currentUser || !currentUser.id || currentUser.id === 'anonymous') {
        throw new Error('用户未登录，无法初始化聊天服务')
      }

      // 确保user_id是数字
      const userId = parseInt(currentUser.id)
      if (isNaN(userId) || userId <= 0) {
        throw new Error('用户ID格式错误，无法初始化聊天服务')
      }

      // 检查服务器URL是否有效
      if (!this.serverUrl || !this.serverUrl.startsWith('ws')) {
        throw new Error(`WebSocket服务器地址无效: ${this.serverUrl}`)
      }

      // 构建连接URL
      const wsUrl = `${this.serverUrl}?user_id=${userId}&user_name=${encodeURIComponent(currentUser.name)}&client_id=${Date.now()}`
      
      console.log('创建新的WebSocket连接:', wsUrl)
      
      // 创建WebSocket连接并设置超时
      return new Promise((resolve, reject) => {
        try {
          this.ws = new WebSocket(wsUrl)
          
          // 设置连接超时
          const connectionTimeout = setTimeout(() => {
            if (!this.isConnected) {
              console.error('WebSocket连接超时')
              this.ws.close()
              reject(new Error('WebSocket连接超时，请检查网络或服务器状态'))
            }
          }, 10000) // 10秒超时
          
          // 设置事件监听
          this.setupEventListeners(() => {
            clearTimeout(connectionTimeout)
            resolve()
          }, reject)
          
        } catch (error) {
          reject(new Error(`WebSocket连接创建失败: ${error.message}`))
        }
      })
      
    } catch (error) {
      console.error('WebSocket 初始化失败:', error)
      // 通知状态变化
      this.notifyStatusChange('error')
      throw error
    }
  }

  // 请求在线用户列表（简化版本，不依赖服务器响应）
  requestOnlineUsers() {
    if (!this.isConnected || !this.ws || this.ws.readyState !== WebSocket.OPEN) {
      console.log('WebSocket未连接，无法请求在线用户列表')
      return Promise.resolve([...this.onlineUserSet])
    }
    
    try {
      const message = {
        type: 'get_online_users',
        data: {},
        timestamp: new Date().toISOString()
      }
      
      console.log('请求在线用户列表:', JSON.stringify(message))
      this.ws.send(JSON.stringify(message))
      
      // 返回当前缓存的在线用户列表
      // 服务器会通过 online_users 消息推送最新的列表
      return Promise.resolve([...this.onlineUserSet])
    } catch (error) {
      console.error('请求在线用户列表失败:', error)
      return Promise.resolve([...this.onlineUserSet])
    }
  }
  
  // 设置事件监听
  setupEventListeners(onSuccess = null, onError = null) {
    if (!this.ws) {
      if (onError) onError(new Error('WebSocket实例不存在'))
      return
    }

    // 连接打开
    this.ws.onopen = async (event) => {
      console.log('WebSocket 连接已建立')
      this.isConnected = true
      this.reconnectAttempts = 0
      this.startHeartbeat()
      this.notifyStatusChange('connected')
      // 增加活跃用户计数
      updateActiveUsersCount(1)
      
      // 首先恢复缓存的在线用户列表（立即提供初始状态）
      const cachedUsers = this.getCachedOnlineUsers()
      if (cachedUsers.length > 0) {
        // 临时更新在线用户集合
        this.onlineUserSet = new Set(cachedUsers)
        
        // 通知状态变化
        this.notifyStatusChange({
          service: 'websocket',
          status: 'online_users',
          users: cachedUsers
        })
        
        console.log('已恢复缓存的在线用户状态:', cachedUsers.length, '个用户')
      }
      
      // 自动加入全局房间（用于广播消息）
      try {
        await this.joinGlobalRoom()
        
        // 连接成功后，主动请求一次在线用户列表以获取最新状态
        setTimeout(() => {
          this.requestOnlineUsers()
        }, 500) // 缩短延迟时间，更快获取最新状态
      } catch (error) {
        console.warn('加入全局房间失败:', error)
      }
      
      // 调用成功回调
      if (onSuccess) onSuccess()
    }

    // 接收消息
    this.ws.onmessage = (event) => {
      try {
        // 获取原始数据
        let rawData = event.data;
        
        // 记录原始数据以便调试
        console.log('收到WebSocket原始数据:', rawData);
        
        // 数据清理和预处理
        if (typeof rawData === 'string') {
          // 清理可能导致JSON解析错误的字符
          rawData = rawData.trim();
          
          // 检查并修复常见的JSON格式问题
          try {
            // 尝试直接解析
            const data = JSON.parse(rawData);
            this.handleMessage(data);
          } catch (parseError) {
            console.error('JSON解析失败，尝试修复数据:', parseError);
            
            // 尝试修复JSON格式问题
            try {
              // 1. 检查是否有多个JSON对象连在一起
              if (rawData.indexOf('}{') !== -1) {
                console.log('检测到多个JSON对象，尝试分割处理');
                // 提取第一个有效的JSON对象
                const firstJsonMatch = rawData.match(/\{.*?\}/);
                if (firstJsonMatch) {
                  const firstJson = firstJsonMatch[0];
                  console.log('提取的第一个JSON对象:', firstJson);
                  const data = JSON.parse(firstJson);
                  this.handleMessage(data);
                }
              } 
              // 2. 移除非法字符后再尝试解析
              else {
                // 移除可能的换行符、制表符等
                const cleanData = rawData
                  .replace(/[\r\n\t]+/g, '')
                  .replace(/\\n/g, '\\\\n')
                  .replace(/\\r/g, '\\\\r')
                  .replace(/\\t/g, '\\\\t');
                
                console.log('清理后的数据:', cleanData);
                const data = JSON.parse(cleanData);
                this.handleMessage(data);
              }
            } catch (fixError) {
              console.error('修复JSON数据失败:', fixError);
              console.error('无法处理的原始数据:', rawData);
              
              // 记录详细错误信息以便进一步调试
              console.error('错误位置:', parseError.message);
              
              // 尝试记录部分数据以便分析
              try {
                const partialData = rawData.substring(0, 100) + '...';
                console.log('部分数据:', partialData);
              } catch (e) {}
            }
          }
        } else {
          // 如果数据不是字符串（可能是Blob或ArrayBuffer）
          console.log('收到非字符串数据，类型:', typeof rawData);
        }
      } catch (error) {
        console.error('处理WebSocket消息失败:', error);
      }
    }

    // 连接关闭
    this.ws.onclose = (event) => {
      console.log('WebSocket 连接已关闭，代码:', event.code, '原因:', event.reason)
      this.isConnected = false
      this.stopHeartbeat()
      this.notifyStatusChange('disconnected')

      // 连接断开后清空在线用户集合，并广播更新
      const oldOnlineUsers = new Set(this.onlineUserSet)
      this.onlineUserSet.clear()
      
      this.notifyStatusChange({
        service: 'websocket',
        status: 'online_users',
        users: []
      })
      
      // 通知所有用户下线
      if (oldOnlineUsers.size > 0) {
        this.notifyOnlineStatusChange(oldOnlineUsers, new Set())
      }

      // 如果连接尚未成功就关闭，调用错误回调
      if (onError && !this.isConnected) {
        onError(new Error(`WebSocket连接关闭: ${event.reason || '未知原因'}`))
      }

      // 只有在非手动断开且未达到最大重连次数时才自动重连
      if (!this.manualDisconnect && !this.hasReachedMaxAttempts && this.reconnectAttempts < this.maxReconnectAttempts) {
        this.scheduleReconnect()
      } else {
        // 达到最大重连次数，标记为需要手动重试
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
          this.hasReachedMaxAttempts = true
          this.notifyStatusChange('max_attempts_reached')
          console.log(`已达到最大重连次数 (${this.maxReconnectAttempts})，需要手动重试`)
        }
        // 只有在不会重连的情况下才减少活跃用户计数
        updateActiveUsersCount(-1)
      }
    }

    // 连接错误
    this.ws.onerror = (error) => {
      console.error('WebSocket 连接错误:', error)
      this.notifyStatusChange('error')
      
      // 调用错误回调
      if (onError) onError(new Error('WebSocket连接错误'))
    }
  }

  // 处理接收到的消息
  handleMessage(data) {
    console.log('WebSocket收到消息:', data)
    
    switch (data.type) {
      case 'message':
        console.log('处理消息类型消息:', data.data)
        
        const messageObj = {
          id: data.data.id,
          content: data.data.content,
          type: data.data.message_type || 'text',
          timestamp: data.data.timestamp,
          sender: {
            id: data.data.user_id,
            name: data.data.user_name
          },
          roomId: data.data.room_id,
          // 添加消息类型标识
          isBroadcast: data.data.room_id === this.globalRoomId
        }
        
        // 判断消息类型（广播或私聊）
        if (messageObj.isBroadcast) {
          console.log('收到广播消息:', messageObj)
        } else {
          console.log('收到私聊消息:', messageObj)
        }
        
        // 触发通知（如果消息不是自己发送的）
        const currentUser = this.getCurrentUser()
        if (currentUser && messageObj.sender.id != currentUser.id) {
          // 使用静态导入的通知服务
          try {
            // 触发不同类型的通知
            if (messageObj.isBroadcast) {
              // 广播消息通知
              notificationService.showSystemNotification(
                '系统广播',
                messageObj.content,
                { type: 'system' }
              )
            } else {
              // 私聊消息通知
              notificationService.showChatNotification(
                messageObj.sender.name,
                messageObj.content,
                messageObj.sender.id
              )
              
              // 保存通知到本地存储
              this.saveNotification({
                id: `msg_${Date.now()}`,
                title: `来自 ${messageObj.sender.name} 的消息`,
                message: messageObj.content,
                type: 'chat',
                timestamp: new Date().toISOString(),
                isRead: false,
                data: {
                  type: 'chat',
                  userId: messageObj.sender.id,
                  userName: messageObj.sender.name
                }
              })
            }
          } catch (err) {
            console.error('通知服务调用失败:', err)
          }
        }
        
        // 分发消息给所有回调
        this.messageCallbacks.forEach(callback => {
          try {
            console.log('分发消息给回调:', messageObj)
            callback(messageObj)
          } catch (error) {
            console.error('消息回调执行失败:', error)
          }
        })
        break
      
      case 'online_users':
        // 获取旧的在线用户集合进行比较
        const oldOnlineUsers = new Set(this.onlineUserSet)
        
        // 更新在线用户集合
        this.onlineUserSet = new Set(
          Array.isArray(data.data?.users) ? data.data.users.map(u => Number(u.user_id)) : []
        )
        
        console.log('收到在线用户列表更新:', [...this.onlineUserSet])
        
        // 更新最后一次在线用户列表更新时间
        this.lastOnlineUsersUpdate = Date.now()
        
        // 通过状态回调分发在线用户列表
        this.notifyStatusChange({
          service: 'websocket',
          status: 'online_users',
          users: [...this.onlineUserSet]
        })
        
        // 通知在线状态变化
        this.notifyOnlineStatusChange(oldOnlineUsers, this.onlineUserSet)
        break
        
      case 'room_joined':
        console.log('已加入房间:', data.data.room_id)
        // 添加到已加入房间集合
        if (data.data.room_id) {
          this.joinedRooms.add(data.data.room_id)
        }
        // 如果是全局房间，且带有用户ID，则把该用户视为在线
        if (data.data.room_id === this.globalRoomId && data.data.user_id) {
          const userId = Number(data.data.user_id)
          const oldOnlineUsers = new Set(this.onlineUserSet)
          
          if (!this.onlineUserSet.has(userId)) {
            this.onlineUserSet.add(userId)
            
            // 通知状态变化
            this.notifyStatusChange({
              service: 'websocket',
              status: 'online_users',
              users: [...this.onlineUserSet]
            })
            
            // 通知在线状态变化
            this.notifyOnlineStatusChange(oldOnlineUsers, this.onlineUserSet)
          }
        }
        break
        
      case 'room_left':
        console.log('已离开房间:', data.data.room_id)
        // 从已加入房间集合中移除
        if (data.data.room_id && data.data.room_id !== this.globalRoomId) {
          this.joinedRooms.delete(data.data.room_id)
        }
        // 如果是全局房间，带有用户ID，则将其从在线集合移除
        if (data.data.room_id === this.globalRoomId && data.data.user_id) {
          const userId = Number(data.data.user_id)
          const oldOnlineUsers = new Set(this.onlineUserSet)
          
          if (this.onlineUserSet.has(userId)) {
            this.onlineUserSet.delete(userId)
            
            // 通知状态变化
            this.notifyStatusChange({
              service: 'websocket',
              status: 'online_users',
              users: [...this.onlineUserSet]
            })
            
            // 通知在线状态变化
            this.notifyOnlineStatusChange(oldOnlineUsers, this.onlineUserSet)
          }
        }
        break
        
      case 'pong':
        // 心跳响应
        break
        
      default:
        console.log('未知消息类型:', data.type)
    }
  }

  // 发送消息
  async sendMessage(content, roomId = 'default') {
    if (!this.isConnected) {
      throw new Error('WebSocket 未连接')
    }

    try {
      // 检查是否已加入该房间
      if (!this.isInRoom(roomId)) {
        console.log(`尚未加入房间 ${roomId}，尝试自动加入`)
        await this.joinRoom(roomId)
      }

      const message = {
        type: 'message',
        data: {
          room_id: roomId,
          content: content,
          message_type: 'text'
        },
        timestamp: new Date().toISOString()
      }

      console.log('发送WebSocket消息:', JSON.stringify(message))
      this.ws.send(JSON.stringify(message))
      console.log('WebSocket消息已发送')
      
      // 立即返回发送的消息
      return {
        id: Date.now(),
        content: content,
        type: 'text',
        timestamp: new Date().toISOString(),
        sender: this.getCurrentUser(),
        roomId: roomId,
        isBroadcast: roomId === this.globalRoomId
      }
      
    } catch (error) {
      console.error('发送消息失败:', error)
      throw error
    }
  }
  
  // 发送广播消息（发送到全局房间）
  async sendBroadcast(content) {
    console.log('发送广播消息:', content)
    return await this.sendMessage(content, this.globalRoomId)
  }
  
  // 发送私聊消息
  async sendPrivateMessage(content, userId) {
    const currentUser = this.getCurrentUser()
    if (!currentUser || !userId) {
      throw new Error('发送私聊消息需要当前用户和目标用户ID')
    }
    
    // 生成私聊房间ID
    const roomId = this.generatePrivateRoomId([currentUser.id, userId])
    console.log('发送私聊消息:', content, '到房间:', roomId)
    
    return await this.sendMessage(content, roomId)
  }

  // 加入房间
  async joinRoom(roomId) {
    if (!this.isConnected) {
      throw new Error('WebSocket 未连接')
    }

    try {
      const message = {
        type: 'join_room',
        data: {
          room_id: roomId
        },
        timestamp: new Date().toISOString()
      }

      console.log('发送加入房间消息:', JSON.stringify(message))
      this.ws.send(JSON.stringify(message))
      console.log(`已加入房间: ${roomId}`)
      
      // 记录已加入的房间
      this.joinedRooms.add(roomId)
      
    } catch (error) {
      console.error('加入房间失败:', error)
      throw error
    }
  }
  
  // 加入全局房间（用于接收广播消息）
  async joinGlobalRoom() {
    console.log('尝试加入全局房间:', this.globalRoomId)
    await this.joinRoom(this.globalRoomId)
    console.log('成功加入全局房间')
  }
  
  // 生成私聊房间ID
  generatePrivateRoomId(userIds) {
    // 确保userIds是数字数组
    const numericIds = userIds.map(id => parseInt(id)).filter(id => !isNaN(id))
    
    // 排序确保相同的两个用户生成相同的房间ID
    const sortedIds = [...numericIds].sort((a, b) => a - b)
    
    // 使用前缀标识这是私聊房间
    return `${this.defaultPrivateRoomPrefix}${sortedIds.join('_')}`
  }

  // 离开房间
  async leaveRoom(roomId) {
    if (!this.isConnected) {
      return
    }
    
    // 不允许离开全局房间
    if (roomId === this.globalRoomId) {
      console.warn('不能离开全局房间')
      return
    }

    try {
      const message = {
        type: 'leave_room',
        data: {
          room_id: roomId
        },
        timestamp: new Date().toISOString()
      }

      this.ws.send(JSON.stringify(message))
      console.log(`已离开房间: ${roomId}`)
      
      // 从已加入房间集合中移除
      this.joinedRooms.delete(roomId)
      
    } catch (error) {
      console.error('离开房间失败:', error)
    }
  }
  
  // 获取已加入的房间列表
  getJoinedRooms() {
    return Array.from(this.joinedRooms)
  }
  
  // 检查是否已加入某个房间
  isInRoom(roomId) {
    return this.joinedRooms.has(roomId)
  }

  // 获取当前用户
  getCurrentUser() {
    try {
      const currentUser = uni.getStorageSync('currentUser')
      if (currentUser) {
        return JSON.parse(currentUser)
      }
    } catch (error) {
      console.error('获取当前用户失败:', error)
    }
    return { name: '匿名用户', id: 'anonymous' }
  }

  // 开始心跳
  startHeartbeat() {
    this.heartbeatTimer = setInterval(() => {
      if (this.isConnected) {
        this.ws.send(JSON.stringify({ 
          type: 'ping',
          data: { message: 'ping' },
          timestamp: new Date().toISOString()
        }))
      }
    }, this.heartbeatInterval)
  }

  // 停止心跳
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  // 安排重连
  scheduleReconnect() {
    this.reconnectAttempts++
    const backoff = Math.min(this.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1), 30000)
    console.log(`准备重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})，等待 ${backoff}ms`)
    this.notifyStatusChange('reconnecting')
    
    // 清除之前的重连定时器
    if (this.reconnectTimeoutId) {
      clearTimeout(this.reconnectTimeoutId)
    }
    
    this.reconnectTimeoutId = setTimeout(() => { 
      this.init() 
    }, backoff)
  }

  // 监听消息
  onMessage(callback) {
    // 避免重复添加相同的回调
    if (!this.messageCallbacks.includes(callback)) {
      this.messageCallbacks.push(callback)
      console.log('添加消息回调，当前回调数量:', this.messageCallbacks.length)
    }
  }

  // 监听状态变化
  onStatusChange(callback) {
    // 避免重复添加相同的回调
    if (!this.statusCallbacks.includes(callback)) {
      this.statusCallbacks.push(callback)
      console.log('添加状态回调，当前回调数量:', this.statusCallbacks.length)
      // 立即返回当前状态，避免页面错过首次"connected"事件
      try {
        callback({
          service: 'websocket',
          status: this.isConnected ? 'connected' : 'disconnected',
          quota: null
        })
      } catch (e) {
        console.error('立即状态回调执行失败:', e)
      }
    }
  }

  // 移除消息回调
  removeMessageCallback(callback) {
    const index = this.messageCallbacks.indexOf(callback)
    if (index > -1) {
      this.messageCallbacks.splice(index, 1)
      console.log('移除消息回调，当前回调数量:', this.messageCallbacks.length)
    }
  }

  // 移除状态回调
  removeStatusCallback(callback) {
    const index = this.statusCallbacks.indexOf(callback)
    if (index > -1) {
      this.statusCallbacks.splice(index, 1)
      console.log('移除状态回调，当前回调数量:', this.statusCallbacks.length)
    }
  }
  
  // 获取当前在线用户列表
  getOnlineUsers() {
    // 如果最后更新时间超过10秒，且已连接，则主动请求更新
    const now = Date.now()
    if (this.isConnected && (now - this.lastOnlineUsersUpdate > 10000)) {
      console.log('在线用户列表过期，主动请求更新')
      this.requestOnlineUsers().catch(err => {
        console.warn('自动更新在线用户列表失败:', err)
      })
    }
    
    // 返回当前在线用户列表
    const onlineUsers = [...this.onlineUserSet]
    
    // 同时将在线用户列表保存到本地存储，用于页面刷新后快速恢复
    try {
      uni.setStorageSync('cached_online_users', JSON.stringify({
        users: onlineUsers,
        timestamp: Date.now()
      }))
    } catch (error) {
      console.error('保存在线用户缓存失败:', error)
    }
    
    return onlineUsers
  }
  
  // 获取缓存的在线用户列表（用于页面初始加载）
  getCachedOnlineUsers() {
    try {
      const cachedData = uni.getStorageSync('cached_online_users')
      if (cachedData) {
        const data = JSON.parse(cachedData)
        
        // 检查缓存是否过期（5分钟）
        const now = Date.now()
        const isFresh = (now - data.timestamp) < 5 * 60 * 1000
        
        if (isFresh && Array.isArray(data.users)) {
          console.log('使用缓存的在线用户列表:', data.users.length, '个用户')
          return data.users
        }
      }
    } catch (error) {
      console.error('获取缓存在线用户列表失败:', error)
    }
    
    return []
  }

  // 通知状态变化
  notifyStatusChange(status) {
    this.statusCallbacks.forEach(callback => {
      try {
        callback({
          service: 'websocket',
          status: status,
          quota: null
        })
      } catch (error) {
        console.error('状态回调执行失败:', error)
      }
    })
  }
  
  // 通知在线状态变化
  notifyOnlineStatusChange(oldOnlineUsers, newOnlineUsers) {
    // 找出新上线的用户
    const newOnlineIds = [...newOnlineUsers].filter(id => !oldOnlineUsers.has(id))
    
    // 找出新下线的用户
    const newOfflineIds = [...oldOnlineUsers].filter(id => !newOnlineUsers.has(id))
    
    // 记录变化情况
    console.log('在线状态变化:', {
      online: [...newOnlineUsers],
      newOnline: newOnlineIds,
      newOffline: newOfflineIds
    })
    
    // 无论是否有变化，都通知所有回调（确保状态同步）
    this.onlineStatusCallbacks.forEach(callback => {
      try {
        callback({
          online: [...newOnlineUsers],
          newOnline: newOnlineIds,
          newOffline: newOfflineIds
        })
      } catch (error) {
        console.error('在线状态回调执行失败:', error)
      }
    })
  }

  // 获取服务状态
  getServiceStatus() {
    return {
      currentService: 'websocket',
      isInitialized: this.isConnected,
      quota: null,
      availableServices: ['websocket']
    }
  }
  
  // 保存通知到本地存储
  saveNotification(notification) {
    try {
      // 获取现有通知
      const notifications = JSON.parse(uni.getStorageSync('notifications') || '[]')
      
      // 添加新通知
      notifications.unshift(notification)
      
      // 限制通知数量
      const maxNotifications = 50
      if (notifications.length > maxNotifications) {
        notifications.splice(maxNotifications)
      }
      
      // 保存通知
      uni.setStorageSync('notifications', JSON.stringify(notifications))
      
      // 更新通知角标 - 使用静态导入的通知服务
      try {
        notificationService.updateUnreadBadge()
      } catch (err) {
        console.error('更新通知角标失败:', err)
      }
      
      console.log('通知已保存:', notification)
    } catch (error) {
      console.error('保存通知失败:', error)
    }
  }
  
  // 通过通知服务更新角标
  updateNotificationBadge() {
    // 使用静态导入的通知服务更新角标
    try {
      notificationService.updateUnreadBadge()
    } catch (err) {
      console.error('更新通知角标失败:', err)
    }
  }

  // 检查服务是否可用
  isAvailable() {
    return true // WebSocket 服务总是可用
  }

  // 断开连接
  async disconnect() {
    this.stopHeartbeat()
    
    // 清除重连定时器
    if (this.reconnectTimeoutId) {
      clearTimeout(this.reconnectTimeoutId)
      this.reconnectTimeoutId = null
    }
    
    // 标记为手动断开，不自动重连
    this.manualDisconnect = true
    this.hasReachedMaxAttempts = true // 阻止自动重连
    
    // 清理房间状态
    this.joinedRooms.clear()
    
    // 记录旧的在线用户集合
    const oldOnlineUsers = new Set(this.onlineUserSet)
    
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    
    this.isConnected = false
    console.log('WebSocket 聊天服务已断开')
    
    // 清空在线用户集合并通知变化
    this.onlineUserSet.clear()
    if (oldOnlineUsers.size > 0) {
      this.notifyOnlineStatusChange(oldOnlineUsers, new Set())
    }
  }
}

// 创建全局单例并导出（其它模块直接import即可使用）
const chatService = new WebSocketChatService()

export default chatService

// 如需继承或测试，也导出类定义
export { WebSocketChatService }
